home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / DIZZY / SRC / ZAPPER.C < prev   
Text File  |  1990-12-29  |  6KB  |  227 lines

  1. /*
  2. >>    Dizzy 1.0    Zapper.c
  3. >>
  4. >>    A digital circuit simulator & design program for the X Window System
  5. >>
  6. >>    Copyright 1990 Juri Munkki, all rights reserved
  7. >>
  8. >>    Please read the included file called "DizzyDoc" for information on
  9. >>    what your rights are concerning this product.
  10. */
  11.  
  12. #include "dizzy.h"
  13.  
  14. extern    Element *LastElem;    /*    From Arrow.c        */
  15. extern    int     ElemCount;    /*    Also from Arrow.c    */
  16.  
  17. /*
  18. >>    The zapper tool allows the user to delete line segments and
  19. >>    elements. If the mouse button is held down, the user can
  20. >>    browse through the possible objects by moving the mouse.
  21. >>    An object is only deleted after the mouse button is released.
  22. */
  23. void    DoZapperTool()
  24. {
  25.     Element     *elem,*found,*brother;
  26.     int         foundpin;
  27.     long        offs,elemsize;
  28.     int         i,j,downflag;
  29.     Input        *ip;
  30.     Point        MousePoint,oldspot;
  31.     Rect        selector;
  32.     int         typefound;
  33.     int         x1,y1,x2,y2;
  34.  
  35.     ClipEditArea();
  36.     PenSize(5,5);
  37.     PenXor();
  38. #ifdef    MACINTOSH
  39.     SetCursor(*GetCursor(129));
  40. #endif
  41.  
  42.     /*    Prepare the data so that it can be searched backwards.    */
  43.     elemsize=0;
  44.     ElemCount=0;
  45.     for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
  46.     {    elem=(Element *)(SimBase+offs);
  47.         elem->PrevLength=elemsize;
  48.         elemsize=elem->Length;
  49.         ElemCount++;
  50.     }
  51.     LastElem=elem;
  52.  
  53.     typefound=0;
  54.     found=0;
  55.     
  56.     GetMouseDownPoint(&MousePoint);
  57.     oldspot.h= MousePoint.h+9999;    /*    Some improbable point    */
  58.     oldspot.v= MousePoint.v+9999;    /*    to simulate motion.     */
  59.     
  60.     do
  61.     {    downflag=GetMouseTrackEvent(&MousePoint);
  62.         
  63.         /*    Did mouse move? */
  64.         if(MousePoint.h!=oldspot.h || MousePoint.v!=oldspot.v)
  65.         {    if(typefound)    /*    Was there a previous hilite to unhilite?    */
  66.             {    HILITEMODE;
  67.                 if(typefound>0)
  68.                 {    MoveTo(selector.left,selector.top);
  69.                     LineTo(selector.right,selector.bottom);
  70.                 }
  71.                 else
  72.                     InvertRect(&selector);
  73.             }
  74.             typefound=0;    /*    Current hilite==nil                         */
  75.             found=0;
  76.  
  77.             if(PtInRect(MousePoint,&EditClipper))    /*    Mouse in edit area? */
  78.             {    i=ElemCount;
  79.                 elem=LastElem;
  80.                 while(i-- && !found)    /*    Search for a hit in body area.    */
  81.                 {    if(PtInRect(MousePoint,&elem->Body))
  82.                     {    found=elem;
  83.                         typefound= -1;    /*    An element body was found.        */
  84.                         selector=elem->Body;
  85.                         HILITEMODE;     /*    Hilite the found element.        */
  86.                         InvertRect(&selector);
  87.                     }
  88.                     elem=(Element *)(((char *) elem)-elem->PrevLength);
  89.                 }
  90.         
  91.                 if(!typefound)            /*    No element body was found?    */
  92.                 {    i=ElemCount;        /*    Look for a line instead.    */
  93.                     elem=LastElem;
  94.                     while(i-- && !typefound)
  95.                     {    ip=(Input *)&elem->Out[elem->Outputs];
  96.                         for(j=0;j<elem->Inputs;j++)
  97.                         {    if(GetConnectLine(ip,elem,j,&x1,&y1,&x2,&y2))
  98.                             if(PntOnLine(x1,y1,
  99.                                          x2,y2,
  100.                                          MousePoint.h,MousePoint.v)==2)
  101.                             {    typefound=1;    /*    A line was found.    */
  102.                                 found=elem;
  103.                                 foundpin=j;
  104.  
  105.                                 selector.left=x1-LCENTERING;
  106.                                 selector.top=y1-LCENTERING;
  107.                                 selector.right=x2-LCENTERING;
  108.                                 selector.bottom=y2-LCENTERING;
  109.                                 HILITEMODE;     /*    Hilite the found line.    */
  110.                                 MoveTo(selector.left,selector.top);
  111.                                 LineTo(selector.right,selector.bottom);
  112.  
  113.                                 j=elem->Inputs; /*    Fall out of ip-loop.    */
  114.                                 i=0;
  115.                             }
  116.                             ip++;
  117.                         }
  118.                         elem=(Element *)(((char *) elem)-elem->PrevLength);
  119.                     }
  120.                 }
  121.             }
  122.         }
  123.         oldspot=MousePoint;
  124.     }    while(downflag);
  125.  
  126.     if(typefound)        /*    Did we find something?        */
  127.     {    if(typefound>0) /*    Was it a line segment?        */
  128.         {    HILITEMODE; /*    Disconnect line segment.    */
  129.             MoveTo(selector.left,selector.top);
  130.             LineTo(selector.right,selector.bottom);
  131.             ip=(Input *)&found->Out[found->Outputs];
  132.             ip[foundpin].Chip=0;
  133.             ip[foundpin].Pin=0;
  134.             InvalLine(selector.left,selector.top,selector.right,selector.bottom);
  135.         }
  136.         else            /*    It was an element.            */
  137.         {    long    ouroffset;
  138.             int     inptcount,outpcount;
  139.             Input    ip2;
  140.         
  141.             if(found->Type==CONN)    /*    Unsplit lines    */
  142.             {    ip2= *(Input *)&found->Out[1];
  143.             }
  144.             else
  145.             {    ip2.Chip=0;     /*    Disconnect lines.    */
  146.                 ip2.Pin=0;
  147.             }
  148.             
  149.             /*    First, let's invalidate the display.                    */
  150.             if(found->Type==OUTP || found->Type==INPT)
  151.             {    SetTrashRect(&EditClipper);
  152.             }
  153.             else
  154.             {    SetTrashRect(&found->Body);
  155.             }
  156.  
  157.             /*    Find lines connected to inputs of this chip. Easy.        */
  158.             ouroffset=((char *)found)-SimBase;    /*    Our "signature".    */
  159.             ip = (Input *)&found->Out[found->Outputs];
  160.             for(j=0;j<found->Inputs;j++)
  161.             {    if(ip->Chip != ouroffset)
  162.                 if(GetConnectLine(ip,found,j,&x1,&y1,&x2,&y2))
  163.                 {    ExpandTrash(x2,y2);
  164.                 }
  165.                 ip++;
  166.             }
  167.         
  168.             /*    Find lines connected to outputs of this chip. Harder.    */
  169.             for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
  170.             {    elem=(Element *)(SimBase+offs);
  171.                 ip=(Input *)&elem->Out[elem->Outputs];
  172.                 for(j=0;j<elem->Inputs;j++)
  173.                 {    if(ip->Chip == ouroffset)
  174.                     {    GetConnectLine(ip,elem,j,&x2,&y2,&x1,&y1);
  175.                         ExpandTrash(x2,y2);
  176.                     }
  177.                     ip++;
  178.                 }
  179.             }
  180.             InvalTrash();    /*    Invalidate the whole area.    */
  181.  
  182.             inptcount=0;    /*    Number of inputs so far.                */
  183.             outpcount=0;    /*    Number of outputs so far.                */
  184.             
  185.             /*    Disconnect everything from the dead chip.                */
  186.             for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
  187.             {    elem=(Element *)(SimBase+offs);
  188.             
  189.                 if(elem->Type==INPT)
  190.                     elem->PrivData= ++inptcount;
  191.                 else
  192.                 if(elem->Type==OUTP)
  193.                     elem->PrivData= ++outpcount;
  194.  
  195.                 ip=(Input *)&elem->Out[elem->Outputs];
  196.                 for(j=0;j<elem->Inputs;j++)
  197.                 {    if(ip->Chip==ouroffset)
  198.                     {    *ip=ip2;
  199.                     }
  200.                     ip++;
  201.                 }
  202.             }
  203.             HILITEMODE;
  204.             InvertRect(&selector);
  205.  
  206.             found->Type=ZAPP;    /*    Food for garbage collector.         */
  207.             found->Flags=0;
  208.             found->Body=NilRect;
  209.             found->InRect=NilRect;
  210.             found->OutRect=NilRect;
  211.             found->Inputs=0;
  212.             found->Outputs=0;
  213.             
  214.             if(CountElementType(ZAPP)>MAX_ZAPS)
  215.             {    DatabaseCleanup();    /*    Time to garbage collect.        */
  216.             }
  217.         }
  218.     }
  219.  
  220. #ifdef    MACINTOSH
  221.     InitCursor();
  222. #endif
  223.     PenSize(1,1);
  224.     PenCopy();
  225.     RestoreClipping();
  226. }
  227.